/*  
 * i-OSGi - Tunable Bundle Isolation for OSGi
 * Copyright (C) 2011  Sven Schulz
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.iosgi.benchmark;

import java.io.File;
import java.io.FileWriter;
import java.net.URI;
import java.util.Arrays;

import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Provides;
import org.apache.felix.ipojo.annotations.Requires;
import org.iosgi.IsolationAdmin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Sven Schulz
 */
@Component(immediate = true)
@Provides(specifications = { Benchmark.class })
public class IEMaintenance implements Benchmark {

	private static final Logger LOGGER = LoggerFactory
			.getLogger(IEMaintenance.class);

	private static final long RAMP_DOWN_DURATION = 10000;

	@Requires
	private IsolationAdmin admin;

	@Override
	public void perform() throws Exception {
		int iterations = 50;
		File f = new File("ie-maintenance."
				+ Long.toHexString(System.currentTimeMillis()) + ".csv");
		FileWriter w = new FileWriter(f);
		try {
			URI nonPrimordial = admin.spawn(URI.create("/"));
			URI[] roots = new URI[] { /* URI.create("/0"), nonPrimordial, */
			URI.create("/") };
			LOGGER.debug("performing maintenance operations on {}",
					Arrays.toString(roots));
			for (URI r : roots) {
				w.write("Parent," + r + "\n");
				w.write("Create [ns],Destroy [ns]\n");
				perform(r, w, iterations);
				w.write('\n');
			}
			admin.destroy(nonPrimordial);
		} finally {
			w.close();
		}
		LOGGER.debug("result written to {}", f.getAbsolutePath());
	}

	void perform(final URI environmentId, FileWriter w, int iterations)
			throws Exception {
		long[] elapsed = new long[2];
		for (int i = 1; i <= iterations; i++) {
			LOGGER.debug("performing iteration {}/{} on {}", new Object[] { i,
					iterations, environmentId });
			long ref = System.nanoTime();
			URI eid = admin.spawn(environmentId);
			elapsed[0] = System.nanoTime() - ref;
			rampdown();
			ref = System.nanoTime();
			admin.destroy(eid);
			elapsed[1] = System.nanoTime() - ref;
			w.write(Long.toString(elapsed[0]) + ',' + Long.toString(elapsed[1])
					+ '\n');
			rampdown();
		}
	}

	void rampdown() throws InterruptedException {
		LOGGER.debug("waiting for system to stabilize");
		Thread.sleep(RAMP_DOWN_DURATION);
	}

}
